#include "CWidget.h"
#include <QThread>
#include <QRegExpValidator>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
CWidget::CWidget(QWidget *parent)
    : QWidget(parent)
{
#pragma region UI
    this->resize(800, 500);
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    this->setLayout(mainLayout);

    QHBoxLayout *layout = new QHBoxLayout;
    mainLayout->addLayout(layout);

    QLabel *label = new QLabel(this);
    label->setText("RTSP URL:");
    layout->addWidget(label);

    lineEdit = new QLineEdit(this);
    lineEdit->setPlaceholderText("rtsp://0.0.0.0:0/path"); // 设置占位提示
    // lineEdit->setInputMask(">rtsp://xxx.xxx.xxx.xxx:xxxxx/xxxxxxxxxxxxxx");
    // lineEdit 设置格式rtsp://ip:port/mediaRoute, mediaRoute 可以为字符串
    lineEdit->setText("rtsp://127.0.0.1:8554/0");
    lineEdit->setValidator(new QRegExpValidator(QRegExp("rtsp://[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}:[0-9]{1,5}/.*"), this));
    layout->addWidget(lineEdit);

    btnOpen = new QPushButton(this);
    btnOpen->setText("Open");
    layout->addWidget(btnOpen);
    connect(btnOpen, &QPushButton::clicked, this, &CWidget::onBtnOpenClicked);

    btnClose = new QPushButton(this);
    btnClose->setEnabled(false);
    btnClose->setText("Close");
    layout->addWidget(btnClose);
    connect(btnClose, &QPushButton::clicked, this, &CWidget::onBtnCloseClicked);

    // w = new QWidget(this);
    // w->setStyleSheet("background-color: black;");
    // mainLayout->addWidget(w);
    // this->startTimer(1500);
    openglWidget = new Yuv420GLWidget(this);
    mainLayout->addWidget(openglWidget);
#pragma endregion

#pragma region RTSP
    rtspClient = new CPullClient;
    clientThread = new QThread;

    initThread(rtspClient, clientThread);
#pragma endregion

#pragma region Decoder
    rtpDecoder = new RtpDecoder;
    videoWaiter = new VideoWaiter;
    audioRenderer = new AudioRenderer;

    decodeThread = new QThread;
    videoThread = new QThread;
    audioThread = new QThread;

    initThread(rtpDecoder, decodeThread);
    initThread(videoWaiter, videoThread);
    initThread(audioRenderer, audioThread);
#pragma endregion

#pragma region Connect
    connect(this, &CWidget::startConnect, rtspClient, &CPullClient::onStartConnect);
    connect(this, &CWidget::endConnect, rtspClient, &CPullClient::onEndConnect);

    connect(rtspClient, &CPullClient::connected, this, &CWidget::onConnected);
    connect(rtspClient, &CPullClient::disconnected, this, &CWidget::onDisconnected);

    connect(rtspClient, &CPullClient::sendSdp, rtpDecoder, &RtpDecoder::initDecoder);
    connect(rtspClient, &CPullClient::sendRtpData, rtpDecoder, &RtpDecoder::recvRtpData);
    connect(rtspClient, &CPullClient::sendRtcpData, rtpDecoder, &RtpDecoder::recvRtcpData);

    // connect(decoder, &RtpDecoder::initVideoOutput, this, &CWidget::onInitVideoOutput);
    connect(rtpDecoder->videoDecoder, &VideoDecoder::sendVideoFrame, videoWaiter, &VideoWaiter::recvVideoFrame);
    connect(videoWaiter, &VideoWaiter::sendFrame, this, &CWidget::receviceFrame);
    // connect(video, &VideoWaiter::getAudioClock, audio, &AudioRenderer::onGetAudioClock);

    connect(rtpDecoder, &RtpDecoder::initAudioOutput, audioRenderer, &AudioRenderer::onInitAudioOutput);
    connect(rtpDecoder->audioDecoder, &AudioDecoder::sendAudioBuffer, audioRenderer, &AudioRenderer::recvAudioBuffer);
#pragma endregion
}

CWidget::~CWidget()
{
    destroyThread(rtspClient, clientThread);

    destroyThread(rtpDecoder, decodeThread);
    destroyThread(videoWaiter, videoThread);
    destroyThread(audioRenderer, audioThread);
}

void CWidget::timerEvent(QTimerEvent *event)
{
    killTimer(event->timerId());
    openglWidget = new Yuv420GLWidget(this);
    this->layout()->addWidget(openglWidget);
    w->deleteLater();
}

void CWidget::onConnected()
{
    qDebug() << "success To connect : " << lineEdit->text();
    if (btnClose->isEnabled() == false)
    {
        lineEdit->setEnabled(false);
        btnClose->setEnabled(true);
    }
}

inline void CWidget::initThread(QObject *obj, QThread *thread)
{
    if (obj && thread)
    {
        obj->moveToThread(thread);
        thread->start();
    }
}

inline void CWidget::destroyThread(QObject *obj, QThread *thread)
{
    if (obj)
    {
        obj->deleteLater();
    }

    if (thread)
    {
        thread->quit();
        thread->wait();
        thread->deleteLater();
    }
}

void CWidget::onDisconnected()
{
    qDebug() << lineEdit->text() << " was disconnected";

    if (btnOpen->isEnabled() == false)
    {
        btnOpen->setEnabled(true); // 重新启用 开始服务器 按钮
        lineEdit->setEnabled(true);
        btnClose->setEnabled(false); // 同时禁用 关闭服务器 按钮
    }
}

void CWidget::onBtnOpenClicked()
{
    qDebug() << "open button clicked";
    QString url = lineEdit->text();
    btnOpen->setEnabled(false); // 禁止重复发送信号

    emit CWidget::startConnect(url);
}

void CWidget::onBtnCloseClicked()
{
    btnClose->setEnabled(false); // 禁止重复发送信号
    emit CWidget::endConnect();
}

void CWidget::onInitVideoOutput(int format)
{
}

void CWidget::receviceFrame(uint8_t *pixelData, int pixelWidth, int pixelHeight)
{
    if (openglWidget)
        openglWidget->setPixelData(pixelData, pixelWidth, pixelHeight);
    else
        delete pixelData;
}
